package ws.jonas.common.config;

import java.io.IOException;
import java.util.HashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import ws.jonas.common.log.Logger;

/**
 * For each new property:
 * * Add DEFAULT_...
 * * Add ..._KEY
 * * Add in static {}
 * * Add and comment in DEFAULT_CONFIG
 * * Add in config
 */
public class Config {
	private static final String DEFAULT_QUERY_URL = "http://www.systembolaget.se/Sok-dryck/Dryck/?varuNr=%s&action=modaldialog&actiontype=butikdryck";
	private static final String DEFAULT_PRODNR_FILE= "prodnr_file";
	private static final String DEFAULT_LOG_LEVEL = "fine";
	private static final String DEFAULT_MAIL_LOG_LEVEL = "severe";
	private static final String DEFAULT_QUERY_MS = "" + 0;
	private static final String DEFAULT_QUERY_DEVIATION_MS = "" + 0;
	private static final String DEFAULT_CONNECTION_TIMEOUT_MS = "" + 10 * 1000;
	private static final String DEFAULT_CONNECTION_RETRIES = "5";
	private static final String DEFAULT_SMTP_SERVER = "";
	private static final String DEFAULT_SMTP_PORT = "";
	private static final String DEFAULT_SMTP_SENDER = "";
	private static final String DEFAULT_SMTP_USER = "";
	private static final String DEFAULT_SMTP_PASSWORD = "";
	private static final String DEFAULT_SSL_ENABLED = "false";
	private static final String DEFAULT_MAIL_RECIPIENTS = "";
	private static final String DEFAULT_DB_HOST = "";
	private static final String DEFAULT_DB_USER = "";
	private static final String DEFAULT_DB_PASSWORD = "";
	
	public static final String QUERY_URL_KEY = "url";
	public static final String PRODNR_FILE_KEY = "prodnrFile";
	public static final String LOG_LEVEL_KEY = "logLevel";
	public static final String MAIL_LOG_LEVEL = "mailLogLevel";
	public static final String QUERY_MS_KEY = "queryMs";
	public static final String QUERY_DEVIATION_MS_KEY = "queryDeviationMs";
	public static final String CONNECTION_TIMEOUT_MS_KEY = "connTimeoutMs";
	public static final String CONNECTION_RETRIES_KEY = "connRetries";
	public static final String SMTP_SERVER_KEY = "smtpServer";
	public static final String SMTP_PORT_KEY = "smtpPort";
	public static final String SMTP_SENDER_KEY = "smtpSender";
	public static final String SMTP_USER_KEY = "smtpUser";
	public static final String SMTP_PASSWORD_KEY = "smtpPassword";
	public static final String SSL_USAGE_ENABLED = "sslEnabled";
	public static final String MAIL_RECIPIENTS_KEY = "mailRecipients";
	public static final String DB_HOST_KEY = "db";
	public static final String DB_USER_KEY = "dbUser";
	public static final String DB_PASSWORD_KEY = "dbPassword";
	
	private static final String CONFIG_FILE = "sybosc_config.xml";
	
	private static HashMap<String, String> config = new HashMap<String, String>();
	private static final HashMap<String, String> defaultConfig = new HashMap<String, String>();
	
	private static final Logger log = Logger.getInstance(Config.class);
	
	static {
		defaultConfig.put(QUERY_URL_KEY, DEFAULT_QUERY_URL);
		defaultConfig.put(PRODNR_FILE_KEY, DEFAULT_PRODNR_FILE);
		defaultConfig.put(LOG_LEVEL_KEY, DEFAULT_LOG_LEVEL);
		defaultConfig.put(MAIL_LOG_LEVEL, DEFAULT_MAIL_LOG_LEVEL);
		defaultConfig.put(QUERY_MS_KEY, DEFAULT_QUERY_MS);
		defaultConfig.put(QUERY_DEVIATION_MS_KEY, DEFAULT_QUERY_DEVIATION_MS);
		defaultConfig.put(CONNECTION_TIMEOUT_MS_KEY, DEFAULT_CONNECTION_TIMEOUT_MS);
		defaultConfig.put(CONNECTION_RETRIES_KEY, DEFAULT_CONNECTION_RETRIES);
		defaultConfig.put(SMTP_SERVER_KEY, DEFAULT_SMTP_SERVER);
		defaultConfig.put(SMTP_PORT_KEY, DEFAULT_SMTP_PORT);
		defaultConfig.put(SMTP_SENDER_KEY, DEFAULT_SMTP_SENDER);
		defaultConfig.put(SMTP_USER_KEY, DEFAULT_SMTP_USER);
		defaultConfig.put(SMTP_PASSWORD_KEY, DEFAULT_SMTP_PASSWORD);
		defaultConfig.put(SSL_USAGE_ENABLED, DEFAULT_SSL_ENABLED);
		defaultConfig.put(MAIL_RECIPIENTS_KEY, DEFAULT_MAIL_RECIPIENTS);
		defaultConfig.put(DB_HOST_KEY, DEFAULT_DB_HOST);
		defaultConfig.put(DB_USER_KEY, DEFAULT_DB_USER);
		defaultConfig.put(DB_PASSWORD_KEY, DEFAULT_DB_PASSWORD);
		
		resetConfig();
	}
	
	public static void updateConfig() throws IOException {
		resetConfig();
		SAXParser saxParser = null;
		try {
			saxParser = SAXParserFactory.newInstance().newSAXParser();
		} catch (Exception e) {
			log.warning("Could not create config parser");
			log.warning(e);
		}
		
		ConfigParser handler = new ConfigParser(); 
		try {
			saxParser.parse(CONFIG_FILE, handler);
			try {
				Logger.setLevels(config.get(LOG_LEVEL_KEY));
				Logger.setMailLevels(config.get(MAIL_LOG_LEVEL));
			} catch (IllegalArgumentException e) {
				log.warning("Failed to set logger levels");
			}
			log.fine("Parsed config file, updated " + handler.getUpdateCount() + " settings");
		} catch (IOException e) {
			log.severe("Could not parse config file " + e.toString());
			throw(e);
		} catch (SAXException e) {
			log.warning("Could not parse config file, malformed config file: " + e.toString());
		}
	}
	
	public static void set(String key, String value) {
		config.put(key, value);
	}
	
	public static String get(String key) {
		return config.get(key);
	}
	
	public static String getDefault(String key) {
		return defaultConfig.get(key);
	}
	
	public static boolean isValid(String key) {
		return config.containsKey(key);
	}
	
	private static void resetConfig() {
		config.clear();
		config.putAll(defaultConfig);
	}
}
